package com.uapdev.aliddns;

import java.util.List;
import java.util.logging.Logger;

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.alidns.model.v20150109.DescribeSubDomainRecordsRequest;
import com.aliyuncs.alidns.model.v20150109.DescribeSubDomainRecordsResponse;
import com.aliyuncs.alidns.model.v20150109.DescribeSubDomainRecordsResponse.Record;
import com.aliyuncs.alidns.model.v20150109.UpdateDomainRecordRequest;
import com.aliyuncs.alidns.model.v20150109.UpdateDomainRecordResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.utils.StringUtils;
import com.google.gson.Gson;

public class AliMonitor {
	private static final String VERSION="20210705";

	static Logger log = Logger.getLogger(AliMonitor.class.getName());
	private String APPID;
	private String SECRET;

	private AliMonitor() {
	}

	public AliMonitor(String appid, String secret) {
		this.APPID = appid;
		this.SECRET = secret;
	}

	public AliMonitor(String appid, String secret, int getIpReate, int getRecordRate) {
		this.APPID = appid;
		this.SECRET = secret;
		this.getIpReate = getIpReate;
		this.getRecordRate = getRecordRate;
	}

	private int getIpReate = 1000 * 20;// 20秒获取一次ip进行比对
	private int getRecordRate = 1000 * 600;// 10分钟获取一次ddns

	private long oldRecordTime = 0;
	List<Record> recordList;

	/**
	 * 10分钟去获取一次
	 * 
	 * @param subdomain
	 * @param type
	 * @return
	 */
	public List<Record> getRecordId(String subdomain, String type) {
		if (System.currentTimeMillis() - oldRecordTime < getRecordRate) {
			return recordList;
		}
		DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", APPID, SECRET);
		IAcsClient client = new DefaultAcsClient(profile);
		DescribeSubDomainRecordsRequest request = new DescribeSubDomainRecordsRequest();
		request.setRegionId("cn-hangzhou");
		request.setType(StringUtils.isEmpty(type) ? "A" : type);
		request.setPageSize(20L);
		request.setSubDomain(subdomain);
		try {
			DescribeSubDomainRecordsResponse response = client.getAcsResponse(request);
			log.info(new Gson().toJson(response));
			recordList = response.getDomainRecords();
			if (recordList != null && recordList.size() > 0) {
				oldRecordTime = System.currentTimeMillis();
			}
			return recordList;
		} catch (ServerException e) {
			e.printStackTrace();
		} catch (ClientException e) {
			log.warning("getRecordId ErrCode:" + e.getErrCode());
			log.warning("getRecordId ErrMsg:" + e.getErrMsg());
			log.warning("getRecordId RequestId:" + e.getRequestId());
		}
		return null;
	}

	public void updateRecord(String recordId, String rr, String value, String type) {
		DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", APPID, SECRET);
		IAcsClient client = new DefaultAcsClient(profile);
		UpdateDomainRecordRequest request = new UpdateDomainRecordRequest();
		request.setRegionId("cn-hangzhou");
		request.setRecordId(recordId);
		request.setRR(rr);
		request.setValue(value);
		request.setType(StringUtils.isEmpty(type) ? "A" : type);

		try {
			UpdateDomainRecordResponse response = client.getAcsResponse(request);
			oldRecordTime = 0;
			log.info("updated dns record " + new Gson().toJson(response));
		} catch (ServerException e) {
			e.printStackTrace();
		} catch (ClientException e) {
			log.info("updateRecord ErrCode:" + e.getErrCode());
			log.info("updateRecord ErrMsg:" + e.getErrMsg());
			log.info("updateRecord RequestId:" + e.getRequestId());
		}

	}

	public static String getIp() {
		CloseableHttpClient client = HttpClients.createDefault();
		HttpGet httpGet = new HttpGet("http://www.3322.org/dyndns/getip");
		CloseableHttpResponse response = null;
		try {
			response = client.execute(httpGet);
			HttpEntity entity = response.getEntity();
			String ip = EntityUtils.toString(entity, "UTF-8").trim();
			log.info("current ip: " + ip);
			return ip;
		} catch (Exception e) {
			e.printStackTrace();
			log.warning("getip failed" + e.getMessage());
		} finally {
			if (response != null) {
				try {
					response.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		return null;

	}

	public void start(String subdomain) {
		log.info("start monitor version:" + VERSION);
		long oldtime = 0;
		while (true) {
			if ((System.currentTimeMillis() - oldtime) < getIpReate) {
				sleep(300);
				continue;
			}
			String currIp = getIp();
			if (currIp == null || currIp.trim().isEmpty()) {
				log.warning("getIp failed wait 60s");
				sleep(60 * 1000);
				continue;
			}
			List<Record> recodrds = getRecordId(subdomain, null);
			if (recodrds == null || recodrds.size() == 0) {
				log.warning("未在阿里云域名解析维护" + subdomain + "记录或appid secret 错误");
				sleep(5000);
				//System.exit(0);
				continue;
			}

			for (Record record : recodrds) {
				if ("A".equals(record.getType()) && !currIp.equals(record.getValue())) {
					log.info("currIp not equals Record value,need update Record");
					updateRecord(record.getRecordId(), record.getRR(), currIp, record.getType());
					sleep(300);
				}
			}
			oldtime = System.currentTimeMillis();
		}
	}

	private static void sleep(long time) {
		try {
			Thread.sleep(time);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

}
